package com.xuzmian.demo.kotlin

import org.junit.Test

/**
 * 扩展函数：扩展是静态解析的。
 * 扩展不能真正的修改他们所扩展的类。通过定义一个扩展，你并没有在一个类中插入新成员， 仅仅是可以通过该类型的变量用点表达式去调用这个新函数。
 * 扩展函数是静态分发的，即他们不是根据接收者类型的虚方法。 这意味着调用的扩展函数是由函数调用所在的表达式的类型来决定的， 而不是由表达式运行时求值结果决定的。
 */
fun MutableList<Int>.swapInt(index1: Int, index2: Int) {
    val tmp = this[index1] // “this”对应该列表
    this[index1] = this[index2]
    this[index2] = tmp
}

/**
 * 扩展函数:泛化版
 */
fun <T> MutableList<T>.swap(index1: Int, index2: Int) {
    val tmp = this[index1] // “this”对应该列表
    this[index1] = this[index2]
    this[index2] = tmp
}



class ExtensionFunction{

    @Test
    fun testExtensionFunctionForSwap(){
        val list = mutableListOf(1, 2, 3)
        list.swap(0, 2) // “swap()”内部的“this”会保存“list”的值
    }

    open class Shape

    class Rectangle: Shape()

    fun Shape.getName() = "Shape"

    fun Rectangle.getName() = "Rectangle"

    fun printClassName(s: Shape) {
        println(s.getName())
    }


    /**
     * 扩展是静态解析:调用的扩展函数只取决于参数 s 的声明类型，该类型是 Shape 类,尽管实际类型是Rectangle。
     */
    @Test
    fun testExtensionFunctionForStatic(){
        printClassName(Rectangle())
    }
}
